#include "PageCache.hpp"

PageCache PageCache::_sInstan;
// 获取一个k页的span
Span *PageCache::NewSpan(size_t k)
{
    assert(k > 0 && k < NPAGES);
    // 先检查第k个桶里有没有span
    if (!_spanLists[k].Empty())
    {
        return _spanLists->PopFront();
    }
    // 检查后面的桶里面有没有span，如果有就要进行切分
    for (size_t i = k + 1; i < NPAGES; i++)
    { 
        if (!_spanLists[k].Empty())
        {
            Span* nSpan = _spanLists[i].PopFront();//就是第i个位置取一个出来
            //切分成一个k页的span和一个n-k页的span
            //k页的span返回给central cache
            //n-k页的span挂到第n-k桶中去
            Span* kSpan = new Span;
            //在nSpan的头部切一个k页下来
            kSpan->_pageId =nSpan->_pageId;
            kSpan->_n =k;
            nSpan->_pageId+=k;//起始地址+k
            nSpan->_n-=k;
            _spanLists[nSpan->_n].PushFront(nSpan);
            return kSpan;
        }
    }
    //如果走到这里还是没有span那就要去堆里申请128页的span
    Span*bigSpan = new Span;
    void* ptr = SystemAlloc(NPAGES-1);
    bigSpan->_pageId=(PAGE_ID)ptr>>PAGE_SHIFT;
    bigSpan->_n=NPAGES-1;
    _spanLists[bigSpan->_n].PushFront(bigSpan);
    return NewSpan(k);

}